//
// Created by hsj on 2022/1/12.
//

#ifndef CLION_CPP_T_CLASS_H
#define CLION_CPP_T_CLASS_H
//类的访问权限
//类的访问权限有三种（默认private）：
//          public 公共权限： 可以被该类中的函数、子类的函数、其友元函数访问,也可以由该类的对象访问
//          protected 保护权限： 可以被该类中的函数、子类的函数、以及其友元函数访问,但不能被该类的对象访问
//          private 私有权限：只能由该类中的函数、其友元函数访问,不能被任何其他访问，该类的对象也不能访问。

//三种权限的区别（默认private）：
//          public:可以被任意实体访问
//          protected:只允许本类及子类的成员函数访问
//          private:只允许本类的成员函数访问


//继承
//继承的方式有三种（默认private）：
//          公共继承
//          保护继承
//          私有继承

//继承后的属性变化（默认private）:
//          使用private继承,基类的所有方法在子类中变为private;
//          使用protected继承,将基类中public成员变为子类的protected成员，其它成员的访问权限不变；
//          使用public继承,基类中的方法属性不发生改变;

//结合命名空间
namespace my_class_hsj{
    //测试类class
    void test_class();

    //class
    //默认就是private权限
    class Stock{
        //默认就是private权限
        //私有权限直接初始化
        private:
            std::string company;
            long shares;
            double share_val;
            double total_val;
            void set_tot(){//默认就是：inline function (method),inline可以省略
                total_val = shares * share_val;
            };
            //类常量：方式一(避免枚举冲突，使用枚举类c++11)
            enum M_Normal{Months_Normal = 12};
//            enum M_Normal002{Months_Normal = 12};
            int int_value_from_enum = Months_Normal;//隐式转换
            enum class M:unsigned int{Months = 112};
            unsigned int int_value_from_enum_class = static_cast<int>(M::Months);//必须显示转换

            //类常量：方式二（存储在其他的静态变量区域，不和类在一起）
            static const int My_Months = 1112;
        public:
            void acquire(const std::string & co,long n,double pr);
            void buy(long num,double price);
            void sell(long num,double price);
            void update(double price);
            void show() const;//C++11,说明不会修改当前类实例对象
            inline void bye(){//默认就是：inline function (method),inline可以省略
                std::cout<<"_________________________________"<<std::endl;
                std::cout<<"bye bye! "<<std::endl;
            };
            //构造器、析构函数
            Stock();
            Stock(const std::string &company_param,long shares_param = 0,double share_val_param = 0.0);
            ~Stock();

            //this
            const Stock & topValue(const Stock &) const;

            //常量
            void show_enum_const() const;
        protected://子类使用
            void end(){//默认就是：inline function (method),inline可以省略
                std::cout<<"protected end() call bye()! "<<std::endl;
                bye();
            };
    };

    //子类继承
    class StockSub: public Stock{
        public:
           void s_end(){
               std::cout<<"StockSub.s_end() call Stock.end() call Stock.bye()! "<<std::endl;
               end();//调用父类成员函数
           };
        //构造器、析构函数
        StockSub();
        StockSub(const std::string &company_param,long shares_param = 0,double share_val_param = 0.0);
        ~StockSub();
    };
}
namespace my_class_hsj_other{
    //测试多态
    class TestPolymorphic{
    public:
//        测试多态
//        static_cast	用于良性转换，一般不会导致意外发生，风险很低。
//        const_cast	用于 const 与非 const、volatile 与非 volatile 之间的转换。
//        reinterpret_cast	高度危险的转换，这种转换仅仅是对二进制位的重新解释，不会借助已有的转换规则对数据进行调整，但是可以实现最灵活的 C++ 类型转换。
//        dynamic_cast	借助 RTTI（ Run-Time Type Identification），用于类型安全的向下转型（Downcasting）。

        void test_class_polymorphic_rf(my_class_hsj::Stock &);
        void test_class_polymorphic_pointer(my_class_hsj::Stock *);
    };
}
#endif //CLION_CPP_T_CLASS_H
